/* 
 * 创建日期 2011-3-30
 *
 * 成都天和软件公司
 * 电话：028-85425861 
 * 传真：028-85425861-8008 
 * 邮编：610041 
 * 地址：成都市武侯区航空路6号丰德万瑞中心B座1001 
 * 版权所有
 */
package  org.fantasy.cpp.core.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import  org.fantasy.cpp.core.pojo.QueryConfig;
import  org.fantasy.cpp.core.pojo.QueryType;
import  org.fantasy.cpp.core.pojo.SourceInfo;
import  org.fantasy.cpp.core.pool.QryFactoryPool;
import  org.fantasy.cpp.core.service.PageService;
import  org.fantasy.cpp.core.service.QueryService;
import  org.fantasy.cpp.core.util.ParseUtil;
import  org.fantasy.cpp.core.util.QueryCompiler;
import  org.fantasy.common.compile.CompileCenter;
import  org.fantasy.common.db.QryFactory;
import  org.fantasy.common.db.Query;
import  org.fantasy.common.db.bean.ColumnBean;
import  org.fantasy.common.db.bean.Row;
import  org.fantasy.common.util.Constants;
import  org.fantasy.common.util.ResultMap;
import  org.fantasy.common.util.ThreadMap;

/**
 * 查询服务
 * 
 * @author 王文成
 * @version 1.0
 * @since 2011-3-30
 */
@Service("queryService")
public class QueryServiceImpl implements QueryService {

	@Autowired
	private CompileCenter compileCenter;

	@Autowired
	private QryFactoryPool qryFactoryPool;
	
	@Autowired
	private PageService pageService;
	
	public List<Row> qryList(Long queryId, Map<String, Object> qryMap) throws Exception {
		QueryConfig config = pageService.getQueryConfig(queryId);
		return qryList(config,qryMap);
	}
	
	public List<Row> qryPageList(Long queryId, Map<String, Object> qryMap) throws Exception {
		QueryConfig config = pageService.getQueryConfig(queryId);
		return qryPageList(config,qryMap);
	}
	
	@Override
	public List<Row> qryList(QueryConfig config, Map<String, Object> qryMap) throws Exception {
		long type = config.getQueryTypeId();
		if( QueryType.isJSONType(type) ){
			return ParseUtil.json2List(config.getQueryConfig());
		}
		SourceInfo source = config.getSourceInfo();
		QueryCompiler compiler = new QueryCompiler(config, qryMap);
		String sql = compiler.compile(compileCenter);
		QryFactory qryFactory = qryFactoryPool.getQryFactory(source);
		Query query = qryFactory.getQuery(sql, qryMap);
		List<Row> list = query.list();
		saveRuntimeSql(query);
		return list;
	}

	public List<Row> qryPageList(QueryConfig config, Map<String, Object> qryMap) throws Exception {
		long type = config.getQueryTypeId();
		if( QueryType.isJSONType(type) ){
			return ParseUtil.json2List(config.getQueryConfig());
		}
		ResultMap<String, Object> rm = new ResultMap<String, Object>(qryMap);
		int pageStart = rm.getInt(Constants.PAGE_START, Constants.DEF_PAGE_START);
		int pageSize = rm.getInt(Constants.PAGE_SIZE, Constants.DEF_PAGE_SIZE);
		SourceInfo source = config.getSourceInfo();
		QueryCompiler compiler = new QueryCompiler(config, qryMap);
		String sql = compiler.compile(compileCenter);
		QryFactory qryFactory = qryFactoryPool.getQryFactory(source);
		Query query = qryFactory.getQuery(sql, qryMap);
		List<Row> list = query.setPage(pageStart, pageSize).list();
		saveRuntimeSql(query);
		return list;
	}
	
	public int count(QueryConfig config, String sql) throws Exception {
		SourceInfo source = config.getSourceInfo();
		QryFactory qryFactory = qryFactoryPool.getQryFactory(source);
		Query query = qryFactory.getQuery(sql, new HashMap<String, Object>());
		return query.count();
	}
	
	@Override
	public List<ColumnBean> getColumns(Long queryId, Map<String, Object> qryMap) throws Exception {
		QueryConfig config = pageService.getQueryConfig(queryId);
		SourceInfo source = config.getSourceInfo();
		QueryCompiler compiler = new QueryCompiler(config, qryMap);
		String sql = compiler.compile(compileCenter);
		QryFactory qryFactory = qryFactoryPool.getQryFactory(source);
		Query query = qryFactory.getQuery(sql, qryMap);
		return query.getColumns();
	}

	/**
	 * 保存查询SQL
	 * 
	 * @param query
	 */
	private void saveRuntimeSql(Query query) {
		ThreadMap.put(Constants.RUNTIME_QUERY, query.getRuntimeSql());
	}
}
